home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / pvdesk.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-05  |  11.3 KB  |  542 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW INTERFACE                 |
  4. // |  File:        PVDESK.CPP                           |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Desktop support implementation       |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_app
  16. #define uses_colors
  17. #define uses_config
  18. #define uses_ini
  19. #define uses_desk
  20. #define uses_dialog
  21. #define uses_help
  22. #define uses_icons
  23. #define uses_lbox
  24. #define uses_cmdgen
  25.  
  26. #define DECLARE_PVDESK
  27. #include "PVuses.h"
  28. #undef DECLARE_PVDESK
  29.  
  30. void insert_window( Titem *item, int x, int y )
  31. {
  32.   if( is_valid( item ) ) desktop->put_in( item, x, y );
  33. }
  34.  
  35. Tdesktop::Tdesktop( void ):
  36.   Titem( 1, 1 )
  37. {
  38.   backgrnd_attr = pal_desktop.normal;
  39.   max_tileable = 64;
  40.   tile_columns = 1;
  41.   iconize_x = 2;
  42.   iconize_y = yl - 2;
  43.   tile_rect_x = 0;
  44.   tile_rect_y = 0;
  45.   tile_rect_xl = xl;
  46.   tile_rect_yl = yl;
  47. }
  48.  
  49. void Tdesktop::resize( int _xl, int _yl )
  50. {
  51.   iconize_x = 2;
  52.   iconize_y = _yl - 2;
  53.   tile_rect_x = 0;
  54.   tile_rect_y = 0;
  55.   tile_rect_xl = _xl;
  56.   tile_rect_yl = _yl;
  57.   Titem::resize( _xl, _yl );
  58. }
  59.  
  60. void Tdesktop::put_in( Titem *v, int _x, int _y )
  61. {
  62.   Titem::put_in( v, _x, _y ) ;
  63.   update_commands();
  64. }
  65.  
  66. boolean Tdesktop::remove( Titem *v )
  67. {
  68.   if( !Titem::remove( v ) ) return 0;
  69.   update_commands();
  70.   return 1;
  71. }
  72.  
  73. void Tdesktop::update_commands( void )
  74. {
  75.   Titem *p;
  76.   uint f, c, s, t, i;
  77.  
  78.   c = s = t = i = 0;
  79.   p = first();
  80.   while( p != NULL )
  81.   {
  82.     f = p->flags_word;
  83.     if( p->state( isALIVE ) )
  84.     {
  85.       if( f & ifCLOSEABLE  ) c++;
  86.       if( f & ifSELECTABLE ) s++;
  87.       if( f & ifTILEABLE ) t++;
  88.       if( p->state( isICONIZED ) ) i++;
  89.     }
  90.     p = p->nextl();
  91.   }
  92.   if( !s ) set_context( -1 );
  93.   cstate( cmWINDOW_TILE, t != 0 );
  94.   cstate( cmWINDOW_CASCADE, t != 0 );
  95.   cstate( cmWINDOW_ARRANGE_ICONS, i != 0 );
  96.   cstate( cmWINDOW_CLOSE_ALL, c && s != 0);
  97.   cstate( cmWINDOW_NEXT, s > 1 );
  98.   cstate( cmWINDOW_PREVIOUS, s > 1 );
  99. }
  100.  
  101. void Tdesktop::tab_next( int direction )
  102. {
  103.   Titem *p, *l, *ll;
  104.  
  105.   if( current == NULL ) return;
  106.   if( direction > 0 )
  107.   {
  108.     p = ll = current;
  109.     l = last;
  110.     do
  111.     {
  112.       ll = ll->next;
  113.       if( ll->flags( ifSELECTABLE ) && ll->state( isALIVE ) )
  114.       {
  115.         l = p;
  116.         p = ll;
  117.       }
  118.     }
  119.     while( ll != last );
  120.   }
  121.   else
  122.   {
  123.     p = current;
  124.     do
  125.     {
  126.       l = p;
  127.       p = p->next;
  128.     }
  129.     while( ( !p->flags( ifSELECTABLE ) || !p->state( isALIVE ) ) &&
  130.            ( p != current ) );
  131.   }
  132.   if( p != current )
  133.   {
  134.     last = l;
  135.     items_changed = 1;
  136.     pop_top_items();
  137.     p->focus();
  138.   }
  139. }
  140.  
  141. void Tdesktop::close_all( void )
  142. {
  143.   Titem *p;
  144.   int n, i, cancel;
  145.  
  146.   p = first();
  147.   n = 1;
  148.   while( p != NULL )
  149.   {
  150.     if( p->flags( ifCLOSEABLE ) &&
  151.         p->state( isALIVE ) &&
  152.         p->flags( ifSELECTABLE ) ) n++;
  153.     p = p->nextl();
  154.   }
  155.   cancel = 1;
  156.   while( --n )
  157.   {
  158.     p = first();
  159.     i = cancel;
  160.     while( !p->flags( ifCLOSEABLE ) ||
  161.            !p->state( isALIVE ) ||
  162.            !p->flags( ifSELECTABLE ) ||
  163.            --i ) p = p->nextl();
  164.     if( ( message( p, cmDONE ) != p ) && p->state( isALIVE ) ) cancel++;
  165.   }
  166. }
  167.  
  168. static uint square_root( uint x )
  169. {
  170.   uint i, j;
  171.   for( i = 1, j = 0; j <= x; i += 2 )
  172.     j += i;
  173.   return ( i - 1 ) / 2 - 1;
  174. }
  175.  
  176. /*
  177.   Description:
  178.     Try to tile subitems. If tile fails, undo tile and call tile_error().
  179. */
  180. #define dv( n, a )  (( a ) - ( n )+( ( n ) / ( a ) ) * ( a ))
  181. static int r, cl, dx, dy, xx, yy, al, bl, mx, my;
  182.  
  183. void Tdesktop::tile( void )
  184. {
  185.   Titem *p;
  186.   int n, c;
  187.  
  188.   if( last == NULL ) return;
  189.   iconize_x = 2;
  190.   iconize_y = yl - 2;
  191.   tile_rect_x = 0;
  192.   tile_rect_y = 0;
  193.   tile_rect_xl = xl;
  194.   tile_rect_yl = yl;
  195.   message( this, cmARRANGING );
  196.   n = 0;
  197.   p = first();
  198.   while( p != NULL )
  199.   {
  200.     if( !p->state( isICONIZED ) )
  201.       if( p->flags( ifTILEABLE ) && p->state( isALIVE ) )
  202.         n++;
  203.       else
  204.         message( p, cmARRANGING );
  205.     p = p->nextl();
  206.   }
  207.   if( !n ) return;
  208.   if( n > max_tileable )
  209.   {
  210.     if( tile_error != NULL ) tile_error();
  211.   }
  212.   else
  213.   {
  214.     c = square_root( n );
  215.     r = n / c;
  216.     cl = c - n + c * r;
  217.     if( tile_columns )
  218.     {
  219.       mx = tile_rect_yl;
  220.       my = tile_rect_xl;
  221.     }
  222.     else
  223.     {
  224.       mx = tile_rect_xl;
  225.       my = tile_rect_yl;
  226.     }
  227.     al = mx / c; bl = my / r;
  228.     p = last;
  229.     dx = dv( mx, c ); dy = dv( my, r );
  230.     xx = 0; yy = 0;
  231.     do_tile( last );
  232.     redraw();
  233.   }
  234. }
  235.  
  236. /*
  237.   Description:
  238.     Try to cascade subitems. If cascade fails, undo cascade and call
  239.     tile_error().
  240. */
  241. static char undo;
  242.  
  243. void Tdesktop::cascade( void )
  244. {
  245.   Titem *p;
  246.  
  247.   if( last == NULL ) return;
  248.   iconize_x = 2;
  249.   iconize_y = yl - 2;
  250.   tile_rect_x = 0;
  251.   tile_rect_y = 0;
  252.   tile_rect_xl = xl;
  253.   tile_rect_yl = yl;
  254.   message( this, cmARRANGING );
  255.   p = first();
  256.   while( p != NULL )
  257.   {
  258.     if( !p->state( isICONIZED ) && !p->flags( ifTILEABLE ) ) message( p, cmARRANGING );
  259.     p = p->nextl();
  260.   }
  261.   undo = 0; xx = tile_rect_x; yy = tile_rect_y;
  262.   do_cascade( last, 1, 1 );
  263.   if( ( undo ) && ( tile_error ) ) tile_error();
  264.   redraw();
  265. }
  266.  
  267. /*
  268.   Description:
  269.     Arranges all iconized subitems.
  270.   Exit:
  271.     1 if at least one icon has been arranged,
  272.     0 otherwise.
  273. */
  274. boolean Tdesktop::arrange_icons( void )
  275. {
  276.   Titem *p;
  277.   char result;
  278.  
  279.   iconize_y = yl - 2;
  280.   iconize_x = 2;
  281.   result = 0;
  282.   p = first();
  283.   while( p != NULL )
  284.   {
  285.     if( p->state( isICONIZED ) )
  286.     {
  287.       arrange_one_icon( p );
  288.       result = 1;
  289.     }
  290.     p = p->nextl();
  291.   }
  292.   return result;
  293. }
  294.  
  295. /*
  296.   Description:
  297.     Arrange one iconized subitem. Usually called when item is iconized for
  298.     the first time.
  299. */
  300. void Tdesktop::arrange_one_icon( Titem *p )
  301. {
  302.   if( p->state( isICONIZED ) )
  303.   {
  304.     if( iconize_x <= xl - p->xl )
  305.       p->drag( iconize_x, iconize_y );
  306.     else
  307.     {
  308.       if( iconize_y>1 ) iconize_y--; else iconize_y = yl - 2;
  309.       iconize_x = 2;
  310.       p->drag( iconize_x, iconize_y );
  311.     }
  312.     iconize_x += p->xl + 1;
  313.   }
  314. }
  315.  
  316. //Tdesktop protected:
  317.  
  318. #pragma off( unreferenced )
  319. void Tdesktop::calc_bounds( int delta_xl, int delta_yl )
  320. {
  321.   drag( desktop_x, desktop_y );
  322.   resize( desktop_xl, desktop_yl );
  323. }
  324. #pragma on( unreferenced )
  325.  
  326. void Tdesktop::event_handler( Tevent &ev )
  327. {
  328.   backgrnd_char = i_desktop;
  329.   Titem::event_handler( ev );
  330.   switch( ev.code )
  331.   {
  332.     case evCOMMAND:
  333.       switch( ev.CMD_CODE )
  334.       {
  335.         case cmARRANGING:
  336.           tile_rect_x = 0;  tile_rect_y = 0;
  337.           tile_rect_xl = xl; tile_rect_yl = yl;
  338.           if( arrange_icons() )
  339.           {
  340.             tile_rect_yl = yl-5;
  341.             if( tile_rect_yl < iconize_y ) tile_rect_yl = iconize_y-1;
  342.           }
  343.           break;
  344.         case cmWINDOW_NEXT:
  345.           tab_next(  1 ); break;
  346.         case cmWINDOW_PREVIOUS:
  347.           tab_next( -1 ); break;
  348.         case cmWINDOW_TILE:
  349.           tile(); break;
  350.         case cmWINDOW_CASCADE:
  351.           cascade(); break;
  352.         case cmWINDOW_ARRANGE_ICONS:
  353.           arrange_icons(); break;
  354.         case cmWINDOW_CLOSE_ALL:
  355.           close_all(); break;
  356.         case cmWINDOW_LIST:
  357.           list_all(); break;
  358. #ifndef NOHELP
  359.         case cmHELP_CONTENTS:
  360.           online_help( htHELP_CONTENTS ); break;
  361.         case cmHELP_USING:
  362.           online_help( htHELP_ON_HELP ); break;
  363. #endif
  364.         default: goto hot;
  365.       }
  366.       handled( ev );
  367.     hot:
  368.       break;
  369. #ifndef NOMOUSE
  370.     case evMOUSE_DOWN:
  371.       if( ev.INSIDE && ev.CLICKS )
  372.       {
  373.         list_all();
  374.         handled( ev );
  375.       }
  376. #endif
  377.   }
  378. }
  379.  
  380. //Tdesktop private:
  381.  
  382. void Tdesktop::do_tile( Titem *p )
  383. {
  384.   p = p->next; if( p != last ) do_tile( p );
  385.   if( p->flags( ifTILEABLE ) && p->state( isALIVE ) && !p->state( isICONIZED ) )
  386.   {
  387.     if( tile_columns )
  388.     {
  389.       p->drag( tile_rect_x + yy, tile_rect_y + xx );
  390.       p->resize( bl, al );
  391.     }
  392.     else
  393.     {
  394.       p->drag( tile_rect_x + xx, tile_rect_y + yy );
  395.       p->resize( al, bl );
  396.     }
  397.     yy += bl;
  398.     bl += ( !--dy );
  399.     if( yy >= my )
  400.     {
  401.       yy = 0; xx += al;
  402.       r += ( !--cl );
  403.       bl = my / r; dy = dv( my, r );
  404.       al += ( !--dx );
  405.     }
  406.   }
  407. }
  408.  
  409. void Tdesktop::do_cascade( Titem *p, int _x, int _y )
  410. {
  411.   int xls, yls;
  412.  
  413.   p = p->next;
  414.   if( p->flags( ifTILEABLE ) && p->state( isALIVE ) && !p->state( isICONIZED ) )
  415.   {
  416.     if( ( _x > tile_rect_xl ) || ( _y > tile_rect_yl ) )
  417.       undo = 1;
  418.     else
  419.     {
  420.       xls = p->xl; yls = p->yl;
  421.       p->resize( _x, _y );
  422.       if( p != last ) do_cascade( p, p->xl + 1, p->yl + 1 );
  423.       if( undo )
  424.         p->resize( xls, yls );
  425.       else
  426.       {
  427.         p->drag( xx, yy );
  428.         p->resize( tile_rect_xl + tile_rect_x - xx,
  429.                    tile_rect_yl + tile_rect_y - yy );
  430.         xx++; yy++;
  431.       }
  432.     }
  433.   }
  434.   else
  435.     if( p != last ) do_cascade( p, _x, _y );
  436. }
  437.  
  438. #undef dv
  439.  
  440. Tlist_box *__l;
  441.  
  442. boolean list_all_validator( uint x )
  443. {
  444.   Twindow *p;
  445.  
  446.   if( x == cmDELETE )
  447.   {
  448.     if( __l->vcount )
  449.     {
  450.       __l->getdata( __l->vcurrent, &p );
  451.       if( ( message( p, cmDONE ) == p ) || !p->state( isALIVE ) )
  452.         __l->del( __l->vcurrent );
  453.       __l->cstate( cmDELETE, __l->vcount > 0 );
  454.       set_cmd( &( (Twindow *) modal_item)->commands );
  455.     }
  456.     return 0;
  457.   }
  458.   return 1;
  459. }
  460.  
  461. void Tdesktop::list_all( void )
  462. {
  463.   uint i;
  464.   uint r;
  465.   Titem *p;
  466.  
  467. #ifndef NOHELP
  468.   _help( htD_WINDOWS_LIST );
  469. #endif
  470. #ifdef CYR
  471.   dialog( "滿▒║¬ ¡á »░«º«░╢¿▓Ñ" );
  472. #else
  473.   dialog( "Windows list" );
  474. #endif
  475.   validator( list_all_validator );
  476.   _lsize( sizeof( Titem * ) );
  477.   _stay();
  478. #ifdef CYR
  479.   __l = list_box( "|~Å░«º«░╢¿", i, 35, 11 );
  480. #else
  481.   __l = list_box( "|~Windows", i, 35, 11 );
  482. #endif
  483.   p = first();
  484.   i = 1;
  485.   while( p != NULL )
  486.   {
  487.     if( p->flags( ifSELECTABLE ) && p->state( isALIVE ) )
  488.     {
  489.       _ldata( &p );
  490.       __l->add( ((Twindow *)p)->title );
  491.       if( p->state( isON_TOP ) ) i++;
  492.     }
  493.     p = p->nextl();
  494.   }
  495.   __l->at( i );
  496.   nc();
  497. #ifdef CYR
  498.   kbutton( " êºíÑ░¿" );
  499.   cbutton( " ä«í░Ñ " );
  500.   button(  " |~êº▓░¿⌐", cmDELETE )->shortcut = kDEL;
  501.   hbutton( " Å«¼«╣ " );
  502. #else
  503.   kbutton( "Select" );
  504.   cbutton( " Done " );
  505.   button( "|~Delete", cmDELETE )->shortcut = kDEL;
  506.   hbutton( " Help " );
  507. #endif
  508.   p = NULL;
  509.   __l->cstate( cmDELETE, __l->vcount > 0 );
  510.   r = run();
  511.   if( !__l->vcount )
  512.     set_cmd( NULL );
  513.   else
  514.     if( r == cmOK )
  515.     {
  516.       __l->getdata( i, &p );
  517.       if( p != NULL )
  518.       {
  519.         p->set_state( isICONIZED, 0 );
  520.         p->focus();
  521.       }
  522.     }
  523.   DELETE( __l );
  524. }
  525.  
  526. #ifndef NOCONFIG
  527. static void read_params( void )
  528. {
  529.   seek_section( 0, SECTION_DESKTOP );
  530.   ini( VAR_TILE_MODE, desktop->tile_columns, desktop->tile_columns );
  531. }
  532. #endif
  533.  
  534. void __init_desktop( void )
  535. {
  536.   desktop = NEW( Tdesktop );
  537.   application->put_in( desktop, 0, 0 );
  538. #ifndef NOCONFIG
  539.   read_params();
  540. #endif
  541. }
  542.